package com.tongtong.middleware.blockchain.controller;

import cn.hutool.json.JSONUtil;
import com.tongtong.middleware.blockchain.client.web3j.WEB3JService;
import com.tongtong.middleware.blockchain.service.ERC1155Service;
import com.tongtong.middleware.vo.params.erc1155.*;
import com.tongtong.middleware.vo.response.SignTxRes;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import xyz.xtt.common.response.ApiResult;

import java.math.BigInteger;
import java.util.Objects;

@RestController
@RequestMapping("/eth/erc1155")
@RefreshScope
@Slf4j
public class ERC1155Controller {
    @Autowired
    WEB3JService web3jService;
    @Autowired
    ERC1155Service erc1155Service;

    /**
     * 铸造NFT
     */
    @PostMapping("/mintNFT")
    public ApiResult<String> mintNFT(@Valid @RequestBody MintNFTParams request, BindingResult bindingResult) {
        log.info("【成功】/eth/erc1155/mintNFT request:  to=>{} tokenId=>{} amount=>{}",
                request.getTo(), request.getTokenId(), request.getAmount());

        if (bindingResult.hasErrors()) {
            return ApiResult.failure(9527, Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
        }
        SignTxRes res = erc1155Service.mintNFT(request.getTo(), request.getTokenId(), request.getAmount());
        if (!res.getErrMsg().isEmpty()) {
            log.error("【失败】/eth/erc1155/mintNFT response: {}", res.getErrMsg());
            return ApiResult.failure(9527, res.getErrMsg());
        } else {
            log.info("【成功】/eth/erc1155/mintNFT response: {}", res.getHash());
            return ApiResult.ok(res.getHash());
        }
    }
    /**
     * 批量铸造NFT
     */
    @PostMapping("/mintBatchNFT")
    public ApiResult<String> mintBatchNFT(@Valid @RequestBody MintBatchNFTParams request, BindingResult bindingResult) {
        log.info("【成功】/eth/erc1155/mintBatchNFT request:  to=>{} ids=>{} values=>{}",
                request.getTo(), JSONUtil.toJsonStr(request.getIds()), JSONUtil.toJsonStr(request.getValues()));

        if (bindingResult.hasErrors()) {
            return ApiResult.failure(9527, Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
        }
        SignTxRes res = erc1155Service.mintBatchNFT(request.getTo(), request.getIds(), request.getValues());
        if (!res.getErrMsg().isEmpty()) {
            log.error("【失败】/eth/erc1155/mintBatchNFT response: {}", res.getErrMsg());
            return ApiResult.failure(9527, res.getErrMsg());
        } else {
            log.info("【成功】/eth/erc1155/mintBatchNFT response: {}", res.getHash());
            return ApiResult.ok(res.getHash());
        }
    }

    /**
     * 转移NFT
     */
    @PostMapping("/transfer")
    public ApiResult<String> transfer(@Valid @RequestBody TransferParams request, BindingResult bindingResult) {
        log.info("【成功】/eth/erc1155/transfer request:  from=>{} to=>{} tokenId=>{} amount=>{}",
                request.getFrom(), request.getTo(), request.getTokenId(), request.getAmount());
        if (bindingResult.hasErrors()) {
            return ApiResult.failure(9527, Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
        }
        SignTxRes res = erc1155Service.transfer(request.getFrom(), request.getTo(), request.getTokenId(), request.getAmount());
        if (!res.getErrMsg().isEmpty()) {
            log.error("【失败】/eth/erc1155/transfer response: {}", res.getErrMsg());
            return ApiResult.failure(9527, res.getErrMsg());
        } else {
            log.info("【成功】/eth/erc1155/transfer response: {}", res.getHash());
            return ApiResult.ok(res.getHash());
        }
    }

    /**
     * 批量转移NFT
     */
    @PostMapping("/transferBatch")
    public ApiResult<String> transferBatch(@Valid @RequestBody TransferBatchParams request, BindingResult bindingResult) {
        log.info("【成功】/eth/erc1155/transferBatch request:  from=>{} to=>{} ids=>{} amounts=>{}",
                request.getFrom(), request.getTo(), JSONUtil.toJsonStr(request.getIds()), JSONUtil.toJsonStr(request.getAmounts()));
        if (bindingResult.hasErrors()) {
            return ApiResult.failure(9527, Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
        }
        SignTxRes res = erc1155Service.transferBatch(request.getFrom(), request.getTo(), request.getIds(), request.getAmounts());
        if (!res.getErrMsg().isEmpty()) {
            log.error("【失败】/eth/erc1155/transferBatch response: {}", res.getErrMsg());
            return ApiResult.failure(9527, res.getErrMsg());
        } else {
            log.info("【成功】/eth/erc1155/transferBatch response: {}", res.getHash());
            return ApiResult.ok(res.getHash());
        }
    }

    /**
     * 授权角色
     */
    @PostMapping("/approval")
    public ApiResult<String> approval(@Valid @RequestBody ApprovalParams request, BindingResult bindingResult) {
        log.info("【成功】/eth/erc1155/approval request:  account=>{}",
                request.getAccount());
        if (bindingResult.hasErrors()) {
            return ApiResult.failure(9527, Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
        }
        SignTxRes res = erc1155Service.approval(request.getAccount());
        if (!res.getErrMsg().isEmpty()) {
            log.error("【失败】/eth/erc1155/approval response: {}", res.getErrMsg());
            return ApiResult.failure(9527, res.getErrMsg());
        } else {
            log.info("【成功】/eth/erc1155/approval response: {}", res.getHash());
            return ApiResult.ok(res.getHash());
        }
    }

    /**
     * 销毁NFT
     */
    @PostMapping("/burnNFT")
    public ApiResult<String> burnNFT(@Valid @RequestBody BurnNFTParams request, BindingResult bindingResult) {
        log.info("【成功】/eth/erc1155/burnNFT request:  account=>{} tokenId=>{} amount=>{}",
                request.getAccount(), request.getTokenId(), request.getAmount());
        if (bindingResult.hasErrors()) {
            return ApiResult.failure(9527, Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
        }
        SignTxRes res = erc1155Service.burnNFT(request.getAccount(), request.getTokenId(), request.getAmount());
        if (!res.getErrMsg().isEmpty()) {
            log.error("【失败】/eth/erc1155/burnNFT response: {}", res.getErrMsg());
            return ApiResult.failure(9527, res.getErrMsg());
        } else {
            log.info("【成功】/eth/erc1155/burnNFT response: {}", res.getHash());
            return ApiResult.ok(res.getHash());
        }
    }
    /**
     * 批量销毁NFT
     */
    @PostMapping("/burnBatchNFT")
    public ApiResult<String> burnBatchNFT(@Valid @RequestBody BurnBatchNFTParams request, BindingResult bindingResult) {
        log.info("【成功】/eth/erc1155/burnBatchNFT request:  account=>{} ids=>{} values=>{}",
                request.getAccount(),  JSONUtil.toJsonStr(request.getIds()),  JSONUtil.toJsonStr(request.getValues()));
        if (bindingResult.hasErrors()) {
            return ApiResult.failure(9527, Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
        }
        SignTxRes res = erc1155Service.burnBatchNFT(request.getAccount(), request.getIds(), request.getValues());
        if (!res.getErrMsg().isEmpty()) {
            log.error("【失败】/eth/erc1155/burnBatchNFT response: {}", res.getErrMsg());
            return ApiResult.failure(9527, res.getErrMsg());
        } else {
            log.info("【成功】/eth/erc1155/burnBatchNFT response: {}", res.getHash());
            return ApiResult.ok(res.getHash());
        }
    }

    /**
     * 查询指定用户拥有指定TokenID的数量
     */
    @GetMapping("/balanceOf")
    public ApiResult<String> balanceOf(@RequestParam("account") String account, @RequestParam("tokenId") BigInteger tokenId) {
        if (account == null || account.length() != 42) {
            return ApiResult.failure(9527, "account is illegal");
        }
        if (tokenId == null || tokenId.compareTo(BigInteger.ZERO) <= 0) {
            return ApiResult.failure(9527, "tokenId is illegal");
        }
        String res = erc1155Service.balanceOf(account, tokenId);

        return ApiResult.ok(res);
    }

    /**
     * 查询用户是否被指定操作者授权
     */
    @GetMapping("/isApprovedForAll")
    public ApiResult<String> isApprovedForAll(@RequestParam("account") String account, @RequestParam("operator") String operator) {
        if (account == null || account.length() != 42) {
            return ApiResult.failure(9527, "account is illegal");
        }
        if (operator == null || operator.length() != 42) {
            return ApiResult.failure(9527, "operator is illegal");
        }
        String res = erc1155Service.isApprovedForAll(account, operator);
        return ApiResult.ok(res);
    }

    /**
     * 查询指定TokenID的TokenURI
     */
    @GetMapping("/tokenURI")
    public ApiResult<String> tokenURI(@RequestParam("tokenId") BigInteger tokenId) {
        if (tokenId == null || tokenId.compareTo(BigInteger.ZERO) <= 0) {
            return ApiResult.failure(9527, "tokenId is illegal");
        }
        String res = erc1155Service.uri(tokenId);
        return ApiResult.ok(res);
    }
}
